home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / hity wydania / Ubuntu 9.10 PL / karmelkowy-koliberek-desktop-9.10-i386-PL.iso / casper / filesystem.squashfs / usr / share / pyshared / chardet / chardistribution.py < prev    next >
Text File  |  2006-10-21  |  9KB  |  201 lines

  1. ######################## BEGIN LICENSE BLOCK ########################
  2. # The Original Code is Mozilla Communicator client code.
  3. # The Initial Developer of the Original Code is
  4. # Netscape Communications Corporation.
  5. # Portions created by the Initial Developer are Copyright (C) 1998
  6. # the Initial Developer. All Rights Reserved.
  7. # Contributor(s):
  8. #   Mark Pilgrim - port to Python
  9. #
  10. # This library is free software; you can redistribute it and/or
  11. # modify it under the terms of the GNU Lesser General Public
  12. # License as published by the Free Software Foundation; either
  13. # version 2.1 of the License, or (at your option) any later version.
  14. # This library is distributed in the hope that it will be useful,
  15. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  17. # Lesser General Public License for more details.
  18. # You should have received a copy of the GNU Lesser General Public
  19. # License along with this library; if not, write to the Free Software
  20. # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  21. # 02110-1301  USA
  22. ######################### END LICENSE BLOCK #########################
  23.  
  24. import constants
  25. from euctwfreq import EUCTWCharToFreqOrder, EUCTW_TABLE_SIZE, EUCTW_TYPICAL_DISTRIBUTION_RATIO
  26. from euckrfreq import EUCKRCharToFreqOrder, EUCKR_TABLE_SIZE, EUCKR_TYPICAL_DISTRIBUTION_RATIO
  27. from gb2312freq import GB2312CharToFreqOrder, GB2312_TABLE_SIZE, GB2312_TYPICAL_DISTRIBUTION_RATIO
  28. from big5freq import Big5CharToFreqOrder, BIG5_TABLE_SIZE, BIG5_TYPICAL_DISTRIBUTION_RATIO
  29. from jisfreq import JISCharToFreqOrder, JIS_TABLE_SIZE, JIS_TYPICAL_DISTRIBUTION_RATIO
  30.  
  31. ENOUGH_DATA_THRESHOLD = 1024
  32. SURE_YES = 0.99
  33. SURE_NO = 0.01
  34.  
  35. class CharDistributionAnalysis:
  36.     def __init__(self):
  37.         self._mCharToFreqOrder = None # Mapping table to get frequency order from char order (get from GetOrder())
  38.         self._mTableSize = None # Size of above table
  39.         self._mTypicalDistributionRatio = None # This is a constant value which varies from language to language, used in calculating confidence.  See http://www.mozilla.org/projects/intl/UniversalCharsetDetection.html for further detail.
  40.         self.reset()
  41.         
  42.     def reset(self):
  43.         """reset analyser, clear any state"""
  44.         self._mDone = constants.False # If this flag is set to constants.True, detection is done and conclusion has been made
  45.         self._mTotalChars = 0 # Total characters encountered
  46.         self._mFreqChars = 0 # The number of characters whose frequency order is less than 512
  47.  
  48.     def feed(self, aStr, aCharLen):
  49.         """feed a character with known length"""
  50.         if aCharLen == 2:
  51.             # we only care about 2-bytes character in our distribution analysis
  52.             order = self.get_order(aStr)
  53.         else:
  54.             order = -1
  55.         if order >= 0:
  56.             self._mTotalChars += 1
  57.             # order is valid
  58.             if order < self._mTableSize:
  59.                 if 512 > self._mCharToFreqOrder[order]:
  60.                     self._mFreqChars += 1
  61.  
  62.     def get_confidence(self):
  63.         """return confidence based on existing data"""
  64.         # if we didn't receive any character in our consideration range, return negative answer
  65.         if self._mTotalChars <= 0:
  66.             return SURE_NO
  67.  
  68.         if self._mTotalChars != self._mFreqChars:
  69.             r = self._mFreqChars / ((self._mTotalChars - self._mFreqChars) * self._mTypicalDistributionRatio)
  70.             if r < SURE_YES:
  71.                 return r
  72.  
  73.         # normalize confidence (we don't want to be 100% sure)
  74.         return SURE_YES
  75.  
  76.     def got_enough_data(self):
  77.         # It is not necessary to receive all data to draw conclusion. For charset detection,
  78.         # certain amount of data is enough
  79.         return self._mTotalChars > ENOUGH_DATA_THRESHOLD
  80.  
  81.     def get_order(self, aStr):
  82.         # We do not handle characters based on the original encoding string, but 
  83.         # convert this encoding string to a number, here called order.
  84.         # This allows multiple encodings of a language to share one frequency table.
  85.         return -1
  86.     
  87. class EUCTWDistributionAnalysis(CharDistributionAnalysis):
  88.     def __init__(self):
  89.         CharDistributionAnalysis.__init__(self)
  90.         self._mCharToFreqOrder = EUCTWCharToFreqOrder
  91.         self._mTableSize = EUCTW_TABLE_SIZE
  92.         self._mTypicalDistributionRatio = EUCTW_TYPICAL_DISTRIBUTION_RATIO
  93.  
  94.     def get_order(self, aStr):
  95.         # for euc-TW encoding, we are interested 
  96.         #   first  byte range: 0xc4 -- 0xfe
  97.         #   second byte range: 0xa1 -- 0xfe
  98.         # no validation needed here. State machine has done that
  99.         if aStr[0] >= '\xC4':
  100.             return 94 * (ord(aStr[0]) - 0xC4) + ord(aStr[1]) - 0xA1
  101.         else:
  102.             return -1
  103.  
  104. class EUCKRDistributionAnalysis(CharDistributionAnalysis):
  105.     def __init__(self):
  106.         CharDistributionAnalysis.__init__(self)
  107.         self._mCharToFreqOrder = EUCKRCharToFreqOrder
  108.         self._mTableSize = EUCKR_TABLE_SIZE
  109.         self._mTypicalDistributionRatio = EUCKR_TYPICAL_DISTRIBUTION_RATIO
  110.  
  111.     def get_order(self, aStr):
  112.         # for euc-KR encoding, we are interested 
  113.         #   first  byte range: 0xb0 -- 0xfe
  114.         #   second byte range: 0xa1 -- 0xfe
  115.         # no validation needed here. State machine has done that
  116.         if aStr[0] >= '\xB0':
  117.             return 94 * (ord(aStr[0]) - 0xB0) + ord(aStr[1]) - 0xA1
  118.         else:
  119.             return -1;
  120.  
  121. class GB2312DistributionAnalysis(CharDistributionAnalysis):
  122.     def __init__(self):
  123.         CharDistributionAnalysis.__init__(self)
  124.         self._mCharToFreqOrder = GB2312CharToFreqOrder
  125.         self._mTableSize = GB2312_TABLE_SIZE
  126.         self._mTypicalDistributionRatio = GB2312_TYPICAL_DISTRIBUTION_RATIO
  127.  
  128.     def get_order(self, aStr):
  129.         # for GB2312 encoding, we are interested 
  130.         #  first  byte range: 0xb0 -- 0xfe
  131.         #  second byte range: 0xa1 -- 0xfe
  132.         # no validation needed here. State machine has done that
  133.         if (aStr[0] >= '\xB0') and (aStr[1] >= '\xA1'):
  134.             return 94 * (ord(aStr[0]) - 0xB0) + ord(aStr[1]) - 0xA1
  135.         else:
  136.             return -1;
  137.  
  138. class Big5DistributionAnalysis(CharDistributionAnalysis):
  139.     def __init__(self):
  140.         CharDistributionAnalysis.__init__(self)
  141.         self._mCharToFreqOrder = Big5CharToFreqOrder
  142.         self._mTableSize = BIG5_TABLE_SIZE
  143.         self._mTypicalDistributionRatio = BIG5_TYPICAL_DISTRIBUTION_RATIO
  144.  
  145.     def get_order(self, aStr):
  146.         # for big5 encoding, we are interested 
  147.         #   first  byte range: 0xa4 -- 0xfe
  148.         #   second byte range: 0x40 -- 0x7e , 0xa1 -- 0xfe
  149.         # no validation needed here. State machine has done that
  150.         if aStr[0] >= '\xA4':
  151.             if aStr[1] >= '\xA1':
  152.                 return 157 * (ord(aStr[0]) - 0xA4) + ord(aStr[1]) - 0xA1 + 63
  153.             else:
  154.                 return 157 * (ord(aStr[0]) - 0xA4) + ord(aStr[1]) - 0x40
  155.         else:
  156.             return -1
  157.  
  158. class SJISDistributionAnalysis(CharDistributionAnalysis):
  159.     def __init__(self):
  160.         CharDistributionAnalysis.__init__(self)
  161.         self._mCharToFreqOrder = JISCharToFreqOrder
  162.         self._mTableSize = JIS_TABLE_SIZE
  163.         self._mTypicalDistributionRatio = JIS_TYPICAL_DISTRIBUTION_RATIO
  164.  
  165.     def get_order(self, aStr):
  166.         # for sjis encoding, we are interested 
  167.         #   first  byte range: 0x81 -- 0x9f , 0xe0 -- 0xfe
  168.         #   second byte range: 0x40 -- 0x7e,  0x81 -- oxfe
  169.         # no validation needed here. State machine has done that
  170.         if (aStr[0] >= '\x81') and (aStr[0] <= '\x9F'):
  171.             order = 188 * (ord(aStr[0]) - 0x81)
  172.         elif (aStr[0] >= '\xE0') and (aStr[0] <= '\xEF'):
  173.             order = 188 * (ord(aStr[0]) - 0xE0 + 31)
  174.         else:
  175.             return -1;
  176.         order = order + ord(aStr[1]) - 0x40
  177.         if aStr[1] > '\x7F':
  178.             order =- 1
  179.         return order
  180.  
  181. class EUCJPDistributionAnalysis(CharDistributionAnalysis):
  182.     def __init__(self):
  183.         CharDistributionAnalysis.__init__(self)
  184.         self._mCharToFreqOrder = JISCharToFreqOrder
  185.         self._mTableSize = JIS_TABLE_SIZE
  186.         self._mTypicalDistributionRatio = JIS_TYPICAL_DISTRIBUTION_RATIO
  187.  
  188.     def get_order(self, aStr):
  189.         # for euc-JP encoding, we are interested 
  190.         #   first  byte range: 0xa0 -- 0xfe
  191.         #   second byte range: 0xa1 -- 0xfe
  192.         # no validation needed here. State machine has done that
  193.         if aStr[0] >= '\xA0':
  194.             return 94 * (ord(aStr[0]) - 0xA1) + ord(aStr[1]) - 0xa1
  195.         else:
  196.             return -1
  197.